package com.tianheng.modbus.service;

import io.netty.bootstrap.ServerBootstrap;
import io.netty.channel.*;
import io.netty.channel.nio.NioEventLoopGroup;
import io.netty.channel.socket.SocketChannel;
import io.netty.channel.socket.nio.NioServerSocketChannel;
import io.netty.handler.codec.LengthFieldBasedFrameDecoder;
import io.netty.handler.logging.LogLevel;
import io.netty.handler.logging.LoggingHandler;
import io.netty.handler.timeout.IdleStateHandler;

import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.TimeUnit;

/**************************************************
 * copyright (c) 2020, peng.cao@tianheng-uestc.com All Rights Reserved.
 * created by peng.cao
 * date:       2020/7/10 0010
 * since:      1.0.0.1
 * description:
 *
 **************************************************/
public class TCPServerNetty {

    private int port;
    private static Map<String, Channel> map = new ConcurrentHashMap<String, Channel>();
    private static Map<String, byte[]> messageMap = new ConcurrentHashMap<String, byte[]>();

    public TCPServerNetty(int port) {
        this.port = port;
    }

    public void start() throws Exception {
        EventLoopGroup bossGroup = new NioEventLoopGroup(1);
        EventLoopGroup workerGroup = new NioEventLoopGroup();
        try {
            ServerBootstrap b = new ServerBootstrap();
            b.group(bossGroup, workerGroup)
                    .channel(NioServerSocketChannel.class)
                    .option(ChannelOption.SO_BACKLOG, 1024)
                    .option(ChannelOption.SO_KEEPALIVE, true)
                    .handler(new LoggingHandler(LogLevel.INFO))
                    .childHandler(new ChannelInitializer<SocketChannel>() {
                        @Override
                        public void initChannel(SocketChannel ch) throws Exception {
                            ch.pipeline().addLast(new MyDecoder());
                            ch.pipeline().addLast("idleStateHandler",new IdleStateHandler(30, 0, 0, TimeUnit.SECONDS));
                            ch.pipeline().addLast(new LengthFieldBasedFrameDecoder(Integer.MAX_VALUE, 4, 4, -8, 0));
                            ch.pipeline().addLast(new OutBoundHandler());
                            ch.pipeline().addLast(new InBoundHandler());
//                            ch.pipeline().addLast(new ByteArrayEncoder());
                            ch.pipeline().addLast(new ServerIdleStateTrigger());
                        }
                    });


            ChannelFuture f = b.bind(port).sync();

            System.out.println("启动服务器成功!");

            f.channel().closeFuture().sync();
        } catch (Exception e) {
            e.printStackTrace();
        } finally {

            bossGroup.shutdownGracefully();
            workerGroup.shutdownGracefully();
        }
    }

    public int getPort() {
        return port;
    }

    public void setPort(int port) {
        this.port = port;
    }

    public static Map<String, Channel> getMap() {
        return map;
    }

    public static void setMap(Map<String, Channel> map) {
        TCPServerNetty.map = map;
    }

    public static Map<String, byte[]> getMessageMap() {
        return messageMap;
    }

    public static void setMessageMap(Map<String, byte[]> messageMap) {
        TCPServerNetty.messageMap = messageMap;
    }


}
